<?php
/**
 * 微信公众平台相应操作响应控制器
 *
 * @package    app
 * @version    1.0
 * @author     Ray 33705910@qq.com
 * @license    MIT License
 * @copyright  2013 - 2015 Ray
 * @link       http://wangxiaolei.cn
 */

/**
 * @package  app
 * @extends  Controller
 */
class Controller_WXApi extends Controller{

	public function action_index(){
$post = <<<XML
<?xml version="1.0" encoding="ISO-8859-1"?>
<xml>
	<ToUserName><![CDATA[gh_afe05f9d6be6]]></ToUserName>
	<FromUserName><![CDATA[o4xzTjrt2QBXA_TLs2b4bM325E9Y]]></FromUserName>
	<CreateTime>1421926890</CreateTime>
	<MsgType><![CDATA[text]]></MsgType>
	<Content><![CDATA[你好]]></Content>
	<MsgId>1234567890123456</MsgId>
</xml>
XML;
		$data = simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);

		$account = \Model_WXAccount::find(\Input::get('id'));
		\Session::set('WXAccount', $account);
		$wechat = new \tools\Wechat($data);
		$wechat->init_accounts();
		$wechat->handle();
	}

	/**
	* 微信基础token操作 
	*
	* @param
	* @return
	*/
	public function action_token(){
		$encodingAesKey="1a2818917efc392137042cfa54635d3318522583308";
		$token="doujao";
		$timeStamp="1409304348";
		$nonce="xxxxxx";
		$appId="wx09ff43605964d3fa";
		$text = "<xml><ToUserName><![CDATA[oia2Tj我是中文jewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo]]></Title><Description><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>";
		$encryptMsg = '';
		$pc = new \tools\WXBizMsgCrypt($token, $encodingAesKey, $appId);
		$errCode = $pc->encryptMsg($text, $timeStamp, $nonce, $encryptMsg);
		if($errCode == 0){
			//die("success:" . $encryptMsg);
		} else {
			die($errCode . '##');
		}

		$xml_tree = new DOMDocument();
		$xml_tree->loadXML($encryptMsg);
		$array_e = $xml_tree->getElementsByTagName('Encrypt');
		$array_s = $xml_tree->getElementsByTagName('MsgSignature');
		$encrypt = $array_e->item(0)->nodeValue;
		$msg_sign = $array_s->item(0)->nodeValue;

		$format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>";
		$from_xml = sprintf($format, $encrypt);

		// 第三方收到公众号平台发送的消息
		$msg = '';
		$errCode = $pc->decryptMsg($msg_sign, $timeStamp, $nonce, $from_xml, $msg);
		if ($errCode == 0) {
			print("解密后: " . $msg . "\n");
		} else {
			print($errCode . "\n");
		}
	}

	/**
	* 微信模板消息操作
	* 
	* @param
	* @return
	*/
	public function action_msg_tpl(){
		$last_item = \Model_WebSiteConfig::getByKey('component_verify_ticket_last');
		if( ! $last_item){
			$last_item = \Model_WebSiteConfig::forge(
				array(
					'key' => 'component_verify_ticket_last',
					'value' => '',
					'remark' => '微信服务器上次推送的component_verify_ticket',
				)
			);
			$last_item->save();
		}

		//当前推送记录
		/*$config_item = \Model_WebSiteConfig::query()
				->where('key', 'component_verify_ticket')
				->get_one();*/
		$config_item = \Model_WebSiteConfig::getByKey('component_verify_ticket');
		if( ! $config_item){
			$config_item = \Model_WebSiteConfig::forge(
				array(
					'key' => 'component_verify_ticket',
					'value' => '',
					'remark' => '微信服务器每10分钟推送的component_verify_ticket',
				)
			);
			$config_item->save();
		}
		$last_item->value = $config_item->value;
		$config_item->value = 'AAA';
		$last_item->save();
		$config_item->save();
	}

	/**
	* 事件回调方法
	*
	* 该方法主要针对微信开放平台事件接收
	*/
	public function action_event_callback($type = 'binding'){

		//检验消息是否合法
		if( ! \tools\WechatTools::checkSignature(\Input::get('signature', false), \Input::get('timestamp', false), \Input::get('nonce', false), 'doujao')){
			\Log::error('微信推送component_verify_ticket时验证失败：' . json_encode(\Input::get()));
			die('非法请求');
		}
		$post = $GLOBALS["HTTP_RAW_POST_DATA"];
		$data = simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);
		$crypt = new \tools\WXBizMsgCrypt('doujao', '1a2818917efc392137042cfa54635d3318522583308', $data->AppId);

		$format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%s]]></Encrypt></xml>";
		$from_xml = sprintf($format, $data->Encrypt);
		$msg = '';
		$crypt->decryptMsg(\Input::get('msg_signature', ''), \Input::get('timestamp'), \Input::get('nonce'), $from_xml, $msg);
		$data = simplexml_load_string($msg, 'SimpleXMLElement', LIBXML_NOCDATA);
		if($data->InfoType == 'component_verify_ticket'){
			//上次推送记录
			$last_item = \Model_WebSiteConfig::getByKey('component_verify_ticket_last');
			if( ! $last_item){
				$last_item = \Model_WebSiteConfig::forge(
					array(
						'key' => 'component_verify_ticket_last',
						'value' => '',
						'remark' => '微信服务器上次推送的component_verify_ticket',
					)
				);
				$last_item->save();
			}

			//当前推送记录
			$config_item = \Model_WebSiteConfig::getByKey('component_verify_ticket');
			if( ! $config_item){
				$config_item = \Model_WebSiteConfig::forge(
					array(
						'key' => 'component_verify_ticket',
						'value' => '',
						'remark' => '微信服务器每10分钟推送的component_verify_ticket',
					)
				);
				$config_item->save();
			}
			$last_item->value = $config_item->value;
			$last_item->save();
			$config_item->value = $data->ComponentVerifyTicket;
			$config_item->save();
		}
	}

	/**
	* 微信推送响应程序
	*
	* 主要针对微信的响应操作，共有以下几项：
	* 1.响应文本
	* 2.响应事件
	* 3.响应自定义菜单
	* 4.响应关注/取消关注
	* 5.响应客服
	* @return
	*/
	public function action_action($appid = false){
	
		if( ! $appid){
			die('非法请求');
		}

		if(is_numeric($appid)){
			$account = \Model_WXAccount::find($appid);
		}else{
			$account = \Model_WXAccount::query()
					->where('app_id', $appid)
					->get_one();
		}
		
		if( ! $account){
			die('非法请求');
		}

		\Session::set('WXAccount', $account);
		
		//检验消息是否合法
		if( ! \tools\WechatTools::checkSignature(\Input::get('signature', false), \Input::get('timestamp', false), \Input::get('nonce', false), $account->token)){
			\Log::error('数据验证不合法，不能进入系统...');
			die('非法请求');
		}

		//接入请求
		if(\Input::get('echostr', false)){
			if($account->status != 'NONE'){
				\Log::error('公众号状态未被允许接入');
				die('公众帐户未被允许接入');
			}else{
				die(\Input::get('echostr'));
			}
		}

		//其它请求
		$post = $GLOBALS["HTTP_RAW_POST_DATA"];
		if( ! $post){
			\Log::error('未获取到请求数据');
			die('未获取到请求数据');
		}

		$data = array();
		try{
			$data = simplexml_load_string($post, 'SimpleXMLElement', LIBXML_NOCDATA);
		}catch(Exception $e){
			\Log::error('读取POST数据时，发生异常：' . $e->getMessage());
			die('系统繁忙，请重试!');
		}

		$wechat = new \tools\Wechat($data);
		$wechat->init_accounts();
		$wechat->write_record();
		$wechat->handle();
	}

	/**
	* OAuth2转入
	*
	* 主要针对微信自定义菜单中的view操作而设
	* 计的方法。用于获取微信粉丝openid，并根
	* 据state做相应回馈
	* 
	*/
	public function action_oauth2_callback(){
		$data = \Input::get();
		if( ! isset($data['code']) || ! $data['code']){
			die('无效的参数');
		}
		//参数分析
		if(strpos($data['state'], '@') !== false){
			$params = explode('@', $data['state']);
			$fun =  \Model_WXFunction::query()
					->where('key', $params[0])
					->get_one();
			if(! $fun){
				die('无效的操作');
			}

			$opt = \Factory::instance($fun->value);
			$opt->set_params($data, $params);
			$url = $opt->handler();
			\Response::redirect($url);
		}else{
			die();
		}
	}
}
